home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / utils / file / managers / mc-3.2 / mc-3 / mc-3.2.1 / src / achown.c next >
Encoding:
C/C++ Source or Header  |  1996-05-17  |  14.8 KB  |  672 lines

  1. /* Chown-advanced command -- for the Midnight Commander
  2.    Copyright (C) 1994, 1995 Radek Doulik
  3.  
  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 2 of the License, or
  7.    (at your option) any later version.
  8.  
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; if not, write to the Free Software
  16.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  
  17.  */
  18.  
  19. #include <config.h>
  20. /* Needed for the extern declarations of integer parameters */
  21. #include <sys/types.h>
  22. #include <sys/param.h>
  23. #include <sys/stat.h>
  24. #include <grp.h>
  25. #include <pwd.h>
  26. #ifdef HAVE_UNISTD_H
  27. #   include <unistd.h>
  28. #endif
  29. #include <string.h>
  30. #include <stdio.h>
  31. #include <stdlib.h>        /* For malloc() */
  32. #include "mad.h"
  33. #include "tty.h"
  34. #include "util.h"        /* Needed for the externs */
  35. #include "win.h"
  36. #include "color.h"
  37. #include "dlg.h"
  38. #include "widget.h"
  39. #include "dialog.h"        /* For do_refresh() */
  40. #include "wtools.h"        /* For init_box_colors() */
  41. #include "key.h"        /* XCTRL and ALT macros */
  42.  
  43. #include "dir.h"
  44. #include "panel.h"        /* Needed for the externs */
  45. #include "file.h"
  46. #include "chmod.h"
  47. #include "main.h"
  48.  
  49. #define BX        5
  50. #define BY        6
  51.  
  52. #define TX              50
  53. #define TY              2
  54.  
  55. #define BUTTONS        9
  56.  
  57. #define B_SETALL        B_USER
  58. #define B_SKIP          B_USER + 1
  59.  
  60. #define B_OWN           B_USER + 3
  61. #define B_GRP           B_USER + 4
  62. #define B_OTH           B_USER + 5
  63. #define B_OUSER         B_USER + 6
  64. #define B_OGROUP        B_USER + 7
  65.  
  66. struct {
  67.     int ret_cmd, y, x;
  68.     char *text;
  69.     int hkey, hpos;
  70. } chown_advanced_but [BUTTONS] = {
  71.     { B_CANCEL, 4, 55, "[ Cancel ]", 'c', 2 },
  72.     { B_ENTER, 4, 46, "[ Set ]", 's', 2 },
  73.     { B_SKIP, 4, 36, "[ Skip ]", 'k', 3 },
  74.     { B_SETALL, 4, 23, "[ Set all ]", 'a', 6 },
  75.     { B_ENTER, 0, 48, "[               ]", 0, -1 },
  76.     { B_ENTER, 0, 30, "[               ]", 0, -1 },
  77.     { B_ENTER, 0, 19, "[   ]", 0, -1 },
  78.     { B_ENTER, 0, 11, "[   ]", 0, -1 },
  79.     { B_ENTER, 0, 3, "[   ]", 0, -1 },
  80. };
  81.  
  82. WButton *b_att[3];    /* permission */
  83. WButton *b_user, *b_group;    /* owner */
  84.  
  85. static int files_on_begin;    /* Number of files at startup */
  86. static int flag_pos;
  87. static int x_toggle;
  88. static char ch_flags[11];
  89. static char *ch_perm = "rwx";
  90. static umode_t ch_cmode;
  91. struct stat *sf_stat;
  92. static int need_update;
  93. static int end_chown;
  94. static int current_file;
  95. static int single_set;
  96. static char *fname;
  97.  
  98. static void get_ownership ()
  99. {                /* set buttons  - ownership */
  100.     char *name_t;
  101.  
  102.     name_t = name_trunc (get_owner (sf_stat->st_uid), 15);
  103.     memset (b_user->text + 1, ' ', 15);
  104.     strncpy (b_user->text + 1, name_t, strlen (name_t));
  105.     name_t = name_trunc (get_group (sf_stat->st_gid), 15);
  106.     memset (b_group->text + 1, ' ', 15);
  107.     strncpy (b_group->text + 1, name_t, strlen (name_t));
  108. }
  109.  
  110.  
  111. static int inc_flag_pos (int f_pos)
  112. {
  113.     if (flag_pos == 10) {
  114.     flag_pos = 0;
  115.     return 0;
  116.     }
  117.     flag_pos++;
  118.     if (!(flag_pos % 3) || f_pos > 2)
  119.     return 0;
  120.     return 1;
  121. }
  122.  
  123. static int dec_flag_pos (int f_pos)
  124. {
  125.     if (!flag_pos) {
  126.     flag_pos = 10;
  127.     return 0;
  128.     }
  129.     flag_pos--;
  130.     if (!((flag_pos + 1) % 3) || f_pos > 2)
  131.     return 0;
  132.     return 1;
  133. }
  134.  
  135. static void set_perm_by_flags (char *s, int f_p)
  136. {
  137.     int i;
  138.  
  139.     for (i = 0; i < 3; i++)
  140.     if (ch_flags[f_p + i] == '+')
  141.         s[i] = ch_perm[i];
  142.     else if (ch_flags[f_p + i] == '-')
  143.         s[i] = '-';
  144.     else
  145.         s[i] = (ch_cmode & (1 << (8 - f_p - i))) ? ch_perm[i] : '-';
  146. }
  147.  
  148. static void set_perm (char *s, int p)
  149. {
  150.     s[0] = (p & 4) ? 'r' : '-';
  151.     s[1] = (p & 2) ? 'w' : '-';
  152.     s[2] = (p & 1) ? 'x' : '-';
  153. }
  154.  
  155. static umode_t get_perm (char *s, int base)
  156. {
  157.     umode_t m;
  158.  
  159.     m = 0;
  160.     m |= (s [0] == '-') ? 0 :
  161.     ((s[0] == '+') ? (1 << (base + 2)) : (1 << (base + 2)) & ch_cmode);
  162.  
  163.     m |= (s [1] == '-') ? 0 :
  164.     ((s[1] == '+') ? (1 << (base + 1)) : (1 << (base + 1)) & ch_cmode);
  165.     
  166.     m |= (s [2] == '-') ? 0 :
  167.     ((s[2] == '+') ? (1 << base) : (1 << base) & ch_cmode);
  168.  
  169.     return m;
  170. }
  171.  
  172. static umode_t get_mode ()
  173. {
  174.     umode_t m;
  175.  
  176.     m = ch_cmode ^ (ch_cmode & 0777);
  177.     m |= get_perm (ch_flags, 6);
  178.     m |= get_perm (ch_flags + 3, 3);
  179.     m |= get_perm (ch_flags + 6, 0);
  180.  
  181.     return m;
  182. }
  183.  
  184. static void print_flags (void)
  185. {
  186.     int i;
  187.  
  188.     attrset (COLOR_NORMAL);
  189.  
  190.     for (i = 0; i < 3; i++){
  191.     dlg_move (ch_dlg, BY+1, 9+i);
  192.     addch (ch_flags [i]);
  193.     }
  194.     
  195.     for (i = 0; i < 3; i++){
  196.     dlg_move (ch_dlg, BY + 1, 17 + i);
  197.     addch (ch_flags [i+3]);
  198.     }
  199.     
  200.     for (i = 0; i < 3; i++){
  201.     dlg_move (ch_dlg, BY + 1, 25 + i);
  202.     addch (ch_flags [i+6]);
  203.     }
  204.  
  205.     set_perm_by_flags (b_att[0]->text + 1, 0);
  206.     set_perm_by_flags (b_att[1]->text + 1, 3);
  207.     set_perm_by_flags (b_att[2]->text + 1, 6);
  208.  
  209.     for (i = 0; i < 15; i++){
  210.     dlg_move (ch_dlg, BY+1, 36+i);
  211.     addch (ch_flags[9]);
  212.     }
  213.     for (i = 0; i < 15; i++){
  214.     dlg_move (ch_dlg, BY + 1, 54 + i);
  215.     addch (ch_flags[10]);
  216.     }
  217. }
  218.  
  219. static void update_mode (Dlg_head * h)
  220. {
  221.     print_flags ();
  222.     attrset (COLOR_NORMAL);
  223.     dlg_move (h, BY + 2, 9);
  224.     printw ("%12o", get_mode ());
  225.     send_message (h, h->current->widget, WIDGET_FOCUS, 0);
  226. }
  227.  
  228. static int l_call (void *data)
  229. {
  230.     return 1;
  231. }
  232.  
  233. static int chl_callback (Dlg_head * h, int Par, int Msg)
  234. {
  235.     switch (Msg) {
  236.     case DLG_DRAW:
  237.     attrset (COLOR_NORMAL);
  238.     dlg_erase (h);
  239.     draw_box (h, 0, 0, 13, 17);
  240.     break;
  241.     
  242.     case DLG_KEY:
  243.     switch (Par) {
  244.     case KEY_LEFT:
  245.     case KEY_RIGHT:
  246.         h->running = 0;
  247.         h->ret_value = Par;
  248.     }
  249.     }
  250.     return 0;
  251. }
  252.  
  253. static void do_enter_key (Dlg_head *h, int f_pos)
  254. {
  255.     Dlg_head *chl_dlg;
  256.     WListbox *chl_list;
  257.     struct   passwd *chl_pass;
  258.     struct   group *chl_grp;
  259.     WLEntry  *fe;
  260.     int      lxx, lyy, chl_end, b_pos;
  261.     
  262.     do {
  263.     lxx = (COLS - 74) / 2 + ((f_pos == 3) ? 35 : 53);
  264.     lyy = (LINES - 13) / 2;
  265.     chl_end = 0;
  266.     
  267.     chl_dlg = create_dlg (lyy, lxx, 13, 17, dialog_colors, chl_callback,
  268.                   "[Chown-advanced]", "achown_enter", DLG_NONE);
  269.     
  270.     /* get new listboxes */
  271.     chl_list = listbox_new (1, 1, 15, 11, 0, l_call);
  272.     
  273.     listbox_add_item (chl_list, 0, 0, "<Unknown>", NULL);
  274.     
  275.     if (f_pos == 3) {
  276.         /* get and put user names in the listbox */
  277.         setpwent ();
  278.         while ((chl_pass = getpwent ()))
  279.         listbox_add_item (chl_list, 0, 0, chl_pass->pw_name, NULL);
  280.         
  281.         fe = listbox_search_text (chl_list, get_owner (sf_stat->st_uid));
  282.     }
  283.     else
  284.     {
  285.         /* get and put group names in the listbox */
  286.         setgrent ();    
  287.         while ((chl_grp = getgrent ())) {
  288.         listbox_add_item (chl_list, 0, 0, chl_grp->gr_name, NULL);
  289.         }
  290.         fe = listbox_search_text (chl_list, get_group (sf_stat->st_gid));
  291.     }
  292.     
  293.     if (fe)
  294.         listbox_select_entry (chl_list, fe);
  295.     
  296.     b_pos = chl_list->pos;
  297.     add_widget (chl_dlg, chl_list);
  298.     
  299.     run_dlg (chl_dlg);
  300.     
  301.     if (b_pos != chl_list->pos){
  302.         if (f_pos == 3){
  303.         chl_pass = getpwnam (chl_list->current->text);
  304.         sf_stat->st_uid = chl_pass->pw_uid;
  305.         } else {
  306.         chl_grp = getgrnam (chl_list->current->text);
  307.         sf_stat->st_gid = chl_grp->gr_gid;
  308.         }
  309.         ch_flags [f_pos + 6] = '+';
  310.         get_ownership ();
  311.         dlg_focus (h);
  312.         print_flags ();
  313.     }
  314.     if (chl_dlg->ret_value == KEY_LEFT){
  315.         if (f_pos == 4)
  316.         chl_end = 1;
  317.         dlg_one_up (ch_dlg);
  318.         f_pos--;
  319.     } else if (chl_dlg->ret_value == KEY_RIGHT) {
  320.         if (f_pos == 3)
  321.         chl_end = 1;
  322.         dlg_one_down (ch_dlg);
  323.         f_pos++;
  324.     }
  325.     /* Here we used to redraw the window */
  326.     destroy_dlg (chl_dlg);
  327.     } while (chl_end);
  328. }
  329.  
  330. static void chown_refresh (void)
  331. {
  332.     attrset (COLOR_NORMAL);
  333.     dlg_erase (ch_dlg);
  334.  
  335.     draw_box (ch_dlg, 1, 2, 11, 70);
  336.  
  337.     dlg_move (ch_dlg, BY - 1, 8);
  338.     addstr ("owner");
  339.     dlg_move (ch_dlg, BY - 1, 16);
  340.     addstr ("group");
  341.     dlg_move (ch_dlg, BY - 1, 24);
  342.     addstr ("other");
  343.     
  344.     dlg_move (ch_dlg, BY - 1, 35);
  345.     addstr ("owner");
  346.     dlg_move (ch_dlg, BY - 1, 53);
  347.     addstr ("group");
  348.     
  349.     dlg_move (ch_dlg, 3, 4);
  350.     addstr ("On");
  351.     dlg_move (ch_dlg, BY + 1, 4);
  352.     addstr ("Flag");
  353.     dlg_move (ch_dlg, BY + 2, 4);
  354.     addstr ("Mode");
  355.     
  356.  
  357.     if (!single_set){
  358.     dlg_move (ch_dlg, 3, 54);
  359.     printw ("%6d of %d", files_on_begin - (cpanel->marked) + 1,
  360.            files_on_begin);
  361.     }
  362.  
  363.     print_flags ();
  364.  
  365.     attrset (COLOR_HOT_NORMAL);
  366.     dlg_move (ch_dlg, 1, 24);
  367.     addstr (" Chown advanced command ");
  368. }
  369.  
  370. static void chown_info_update ()
  371. {
  372.     /* display file info */
  373.     attrset (COLOR_NORMAL);
  374.     
  375.     /* name && mode */
  376.     dlg_move (ch_dlg, 3, 8);
  377.     printw ("%s", name_trunc (fname, 45));
  378.     dlg_move (ch_dlg, BY + 2, 9);
  379.     printw ("%12o", get_mode ());
  380.     
  381.     /* permissions */
  382.     set_perm (b_att[0]->text + 1, sf_stat->st_mode >> 6);
  383.     set_perm (b_att[1]->text + 1, sf_stat->st_mode >> 3);
  384.     set_perm (b_att[2]->text + 1, sf_stat->st_mode);
  385. }
  386.  
  387. static void b_setpos (int f_pos) {
  388.     b_att[0]->hotpos=-1;
  389.     b_att[1]->hotpos=-1;
  390.     b_att[2]->hotpos=-1;
  391.     b_att[f_pos]->hotpos = (flag_pos % 3) + 1;
  392. }
  393.  
  394. static int advanced_chown_callback (Dlg_head * h, int Par, int Msg)
  395. {
  396.     int i = 0, f_pos = BUTTONS - h->current->dlg_id - single_set - 1;
  397.  
  398.     switch (Msg) {
  399.     case DLG_DRAW:
  400.     chown_refresh ();
  401.     chown_info_update ();
  402.     return 1;
  403.     
  404.     case DLG_POST_KEY:
  405.     if (f_pos < 3)
  406.         b_setpos (f_pos);
  407.     break;
  408.  
  409.     case DLG_FOCUS:
  410.     if (f_pos < 3) {
  411.         if ((flag_pos / 3) != f_pos)
  412.         flag_pos = f_pos * 3;
  413.         b_setpos (f_pos);
  414.     } else if (f_pos < 5)
  415.         flag_pos = f_pos + 6;
  416.     break;
  417.  
  418.     case DLG_KEY:
  419.     switch (Par) {
  420.         
  421.     case XCTRL('b'):
  422.     case KEY_LEFT:
  423.         if (f_pos < 5)
  424.         return (dec_flag_pos (f_pos));
  425.         break;
  426.         
  427.     case XCTRL('f'):
  428.     case KEY_RIGHT:
  429.         if (f_pos < 5)
  430.         return (inc_flag_pos (f_pos));
  431.         break;
  432.         
  433.     case ' ':
  434.         if (f_pos < 3)
  435.         return 1;
  436.         break;
  437.         
  438.     case '\n':
  439.     case KEY_ENTER:
  440.         if (f_pos <= 2 || f_pos >= 5)
  441.         break;
  442.         do_enter_key (h, f_pos);
  443.         return 1;
  444.         
  445.     case ALT ('x'):
  446.         i++;
  447.         
  448.     case ALT ('w'):
  449.         i++;
  450.         
  451.     case ALT ('r'):
  452.         Par = i + 3;
  453.         for (i = 0; i < 3; i++)
  454.         ch_flags[i * 3 + Par - 3] = (x_toggle & (1 << Par)) ? '-' : '+';
  455.         x_toggle ^= (1 << Par);
  456.         update_mode (h);
  457.         dlg_broadcast_msg (h, WIDGET_DRAW, 0);
  458.         send_message (h, h->current->widget, WIDGET_FOCUS, 0);
  459.         break;
  460.         
  461.     case XCTRL ('x'):
  462.         i++;
  463.         
  464.     case XCTRL ('w'):
  465.         i++;
  466.         
  467.     case XCTRL ('r'):
  468.         Par = i;
  469.         for (i = 0; i < 3; i++)
  470.         ch_flags[i * 3 + Par] = (x_toggle & (1 << Par)) ? '-' : '+';
  471.         x_toggle ^= (1 << Par);
  472.         update_mode (h);
  473.         dlg_broadcast_msg (h, WIDGET_DRAW, 0);
  474.         send_message (h, h->current->widget, WIDGET_FOCUS, 0);
  475.         break;
  476.         
  477.     case 'x':
  478.         i++;
  479.         
  480.     case 'w':
  481.         i++;
  482.         
  483.     case 'r':
  484.         if (f_pos > 2)
  485.         break;
  486.         flag_pos = f_pos * 3 + i;    /* (strchr(ch_perm,Par)-ch_perm); */
  487.         if (((WButton *) h->current->widget)->text[(flag_pos % 3) + 1] == '-')
  488.         ch_flags[flag_pos] = '+';
  489.         else
  490.         ch_flags[flag_pos] = '-';
  491.         update_mode (h);
  492.         break;
  493.  
  494.     case '4':
  495.         i++;
  496.         
  497.     case '2':
  498.         i++;
  499.         
  500.     case '1':
  501.         if (f_pos > 2)
  502.         break;
  503.         flag_pos = i + f_pos * 3;
  504.         ch_flags[flag_pos] = '=';
  505.         update_mode (h);
  506.         break;
  507.         
  508.     case '-':
  509.         if (f_pos > 2)
  510.         break;
  511.         
  512.     case '*':
  513.         if (Par == '*')
  514.         Par = '=';
  515.         
  516.     case '=':
  517.     case '+':
  518.         if (f_pos > 4)
  519.         break;
  520.         ch_flags[flag_pos] = Par;
  521.         update_mode (h);
  522.         advanced_chown_callback (h, KEY_RIGHT, DLG_KEY);
  523.         if (flag_pos>8 || !(flag_pos%3)) dlg_one_down (h);
  524.  
  525.         break;
  526.     }
  527.     return 0;
  528.     }
  529.     return 0;
  530. }
  531.  
  532. static void init_chown_advanced (void)
  533. {
  534.     int i;
  535.  
  536.     sf_stat = (struct stat *) malloc (sizeof (struct stat));
  537.     do_refresh ();
  538.     end_chown = need_update = current_file = 0;
  539.     single_set = (cpanel->marked < 2) ? 2 : 0;
  540.     memset (ch_flags, '=', 11);
  541.     flag_pos = 0;
  542.     x_toggle = 070;
  543.  
  544.     ch_dlg = create_dlg (0, 0, 13, 74, dialog_colors, advanced_chown_callback,
  545.              "[Chown-advanced]", "achown", DLG_CENTER);
  546.  
  547. #define XTRACT(i) BY+chown_advanced_but[i].y, BX+chown_advanced_but[i].x, \
  548.                   chown_advanced_but[i].ret_cmd, chown_advanced_but[i].text, \
  549.                   chown_advanced_but[i].hkey, chown_advanced_but[i].hpos, 0, 0
  550.  
  551.     for (i = 0; i < BUTTONS - 5; i++)
  552.     if (!single_set || i < 2)
  553.         add_widget (ch_dlg, button_new (XTRACT (i)));
  554.  
  555.     b_att[0] = button_new (XTRACT (8));
  556.     b_att[1] = button_new (XTRACT (7));
  557.     b_att[2] = button_new (XTRACT (6));
  558.     b_user = button_new (XTRACT (5));
  559.     b_group = button_new (XTRACT (4));
  560.  
  561.     add_widget (ch_dlg, b_group);
  562.     add_widget (ch_dlg, b_user);
  563.     add_widget (ch_dlg, b_att[2]);
  564.     add_widget (ch_dlg, b_att[1]);
  565.     add_widget (ch_dlg, b_att[0]);
  566. }
  567.  
  568. void chown_advanced_done (void)
  569. {
  570.     free (sf_stat);
  571.     if (need_update)
  572.     update_panels (UP_OPTIMIZE, UP_KEEPSEL, UP_KEEPSEL);
  573.     repaint_screen ();
  574. }
  575.  
  576. #if 0
  577. static inline void do_chown (uid_t u, gid_t g)
  578. {
  579.     chown (cpanel->dir.list[current_file].fname, u, g);
  580.     file_mark (cpanel, current_file, 0);
  581. }
  582. #endif
  583.  
  584. static char *next_file (void)
  585. {
  586.     while (!cpanel->dir.list[current_file].f.marked)
  587.     current_file++;
  588.  
  589.     return cpanel->dir.list[current_file].fname;
  590. }
  591.  
  592. static void apply_advanced_chowns (struct stat *sf)
  593. {
  594.     char *fname;
  595.     gid_t a_gid = sf->st_gid;
  596.     uid_t a_uid = sf->st_uid;
  597.  
  598.     fname = cpanel->dir.list[current_file].fname, get_mode ();
  599.     need_update = end_chown = 1;
  600.     chmod (cpanel->dir.list[current_file].fname, get_mode ());
  601.     chown (fname, (ch_flags[9] == '+') ? sf->st_uid : -1,
  602.        (ch_flags[10] == '+') ? sf->st_gid : -1);
  603.  
  604.     do {
  605.     fname = next_file ();
  606.  
  607.     if (!stat_file (fname, sf))
  608.         break;
  609.     ch_cmode = sf->st_mode;
  610.     chmod (fname, get_mode ());
  611.     chown (fname, (ch_flags[9] == '+') ? a_uid : -1, (ch_flags[10] == '+') ? a_gid : -1);
  612.  
  613.     file_mark (cpanel, current_file, 0);
  614.     cpanel->marked--;
  615.     } while (cpanel->marked);
  616. }
  617.  
  618. void chown_advanced_cmd (void)
  619. {
  620.  
  621.     files_on_begin = cpanel->marked;
  622.  
  623.     do {            /* do while any files remaining */
  624.     init_chown_advanced ();
  625.  
  626.     if (cpanel->marked)
  627.         fname = next_file ();    /* next marked file */
  628.     else
  629.         fname = selection (cpanel)->fname;    /* single file */
  630.  
  631.     if (!stat_file (fname, sf_stat))    /* get status of file */
  632.         break;
  633.     ch_cmode = sf_stat->st_mode;
  634.  
  635.     chown_refresh ();
  636.  
  637.     get_ownership ();
  638.  
  639.     /* game can begin */
  640.     run_dlg (ch_dlg);
  641.  
  642.     switch (ch_dlg->ret_value) {
  643.     case B_CANCEL:
  644.         end_chown = 1;
  645.         break;
  646.  
  647.     case B_ENTER:
  648.         need_update = 1;
  649.         chmod (fname, get_mode ());
  650.         chown (fname, (ch_flags[9] == '+') ? sf_stat->st_uid : -1, (ch_flags[10] == '+') ? sf_stat->st_gid : -1);
  651.         break;
  652.  
  653.     case B_SETALL:
  654.         apply_advanced_chowns (sf_stat);
  655.         break;
  656.  
  657.     case B_SKIP:
  658.         break;
  659.  
  660.     }
  661.  
  662.     if (cpanel->marked && ch_dlg->ret_value != B_CANCEL) {
  663.         file_mark (cpanel, current_file, 0);
  664.         cpanel->marked--;
  665.         need_update = 1;
  666.     }
  667.     destroy_dlg (ch_dlg);
  668.     } while (cpanel->marked && !end_chown);
  669.  
  670.     chown_advanced_done ();
  671. }
  672.